package com.yc.tomcat.core;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLDecoder;

import com.yc.tomcat.util.StringUtil;
import com.yc.web.core.HttpServletRequest;
import com.yc.web.core.HttpServletResponse;
import com.yc.web.core.Servlet;
import com.yc.web.core.ServletRequest;
import com.yc.web.core.ServletResponse;

public class ServerService  implements Runnable{
	private Socket sk = null;
	private InputStream is = null;//用户请求
	private OutputStream os = null;//给用户响应

	public ServerService(Socket sk) {
		this.sk = sk;
	}

	@SuppressWarnings("resource")
	@Override
	public void run() {

		try {
			this.is = sk.getInputStream();
			this.os = sk.getOutputStream();
		} catch (IOException e) {
			e.printStackTrace();
		}
		try {
			//TODO 处理请求 -> 解析请求头协议
			ServletRequest request = new HttpServletRequest(is);


			//TODO 处理请求协议 -> 这个资源是动态资源还是静态资源，如果是静态资源则可以直间以流的方式读取返回即可，如果是动态
			String url = request.getUrl();
			if(StringUtil.checkNull(url)) {
				return;
			}
			
			//处理一下地址中的中文
			try {
				url = URLDecoder.decode(url, "utf-8");
			} catch (Exception e) {
				e.printStackTrace();
			}
			// /fresh/index.html  /fresh /fresh/login
			String temp  = url.substring(1); //去掉最前面的/
			String projectName = "";
			if(!url.contentEquals("/favicon.ico")) {
				projectName = (temp.contains("/") ? temp.substring(0, temp.indexOf("/")) : temp);
			}
			//交给response
			ServletResponse response = new HttpServletResponse(os, "/" + projectName);
			
			//判断该资源类型
			String clazz = ParseUrlPattern.getClass(url);
			if(StringUtil.checkNull(clazz)) { // 说明是静态资源
				response.sendRedirect(url);
				return;
			}
			//动态加载这个处理类
			URLClassLoader loader = null;
			URL classPath = null;
			
			classPath = new URL("file", null, ConstantInfo.BASE_PATH + "\\" +projectName + "\\bin");
			loader = new URLClassLoader(new URL[] {classPath}); //指定类加载器的加载路径
			Class<?> cls = loader.loadClass(clazz); //加载类
			Servlet servlet = (Servlet) cls.newInstance(); //反向生成这个类的一个对象
			servlet.service(request, response); //调用service方法处理
		} catch (Exception e) {
			e.printStackTrace();
			send500(e);
		}
	}
/**
 * 500报错
 * @param e
 */
	private void send500(Exception e) {

		try {
			String responseHeader = "HTTP/1.1 500 Error\r\n\r\n" + e.getMessage();
			os.write(responseHeader.getBytes());
			os.flush();
		} catch (IOException e1) {
			e1.printStackTrace();
		}finally {
			if(os != null) {
				try {
					os.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		}
	}

}
